

#[cfg(test)]
mod tests {
    use std::hash::Hasher;
    use argon2::{Argon2, PasswordHasher};
    use argon2::password_hash::rand_core::OsRng;
    use argon2::password_hash::SaltString;
    use base64::Engine;
    use base64::engine::general_purpose;
    use bincode::{decode_from_slice, encode_to_vec};
    use serde::{Deserialize, Serialize};
    use serde_json::json;
    use twox_hash::XxHash64;
    use crate::utility::jwt::JwtUtil;

    // #[test]
    // fn it_works() {
    //     let secret = "your-secret-key";
    //     let token = "eyJhbGciOiJIUzI1NiJ9.eyJzIjoiNjExNzQwMTM0MDE4MjU2ODk2IiwiZXhwIjoxNzU1NDA1NjE0LCJpIjoxNzU1NDA1NTU0LCJqIjpudWxsfQ.NPHZkm-fVzvQYzsAraAN_gxpRrcfaKlE1zL6-b2iGUg";
    //     JwtUtil::validate_token(&token, &secret).expect("校验失败");
    //
    // }

    // #[test]
    // fn json_test() {
    //     // 生成盐值并哈希密码
    //     let salt = SaltString::generate(&mut OsRng);
    //     let argon2 = Argon2::default();
    //     let password_hash = argon2
    //         .hash_password("123456".as_bytes(), &salt)
    //         .map_err(|e| async_graphql::Error::new(format!("密码处理失败: {}", e))).unwrap();
    //     println!("密码哈希: {}", password_hash.to_string());
    // }

    // 1. 定义数据结构
    #[derive(Serialize, Deserialize, Debug,bincode::Encode, bincode::Decode)]
    // #[repr(C, packed)]
    struct TokenData {
        u: u64,
        r: Vec<String>,
        a: Vec<String>,
        e: u64, // Unix 时间戳
    }




    // #[test]
    // fn aes_256_gcm_test()  {
    //     let token_data = TokenData {
    //         u: 611738073981652992,
    //         r: vec!["user".to_string(), "admin".to_string()],
    //         a: vec!["read".to_string(), "write".to_string()],
    //         e: 1735689600,
    //     };
    //
    //     let bytes = unsafe { std::slice::from_raw_parts(&token_data as *const _ as *const u8, std::mem::size_of::<TokenData>()) };
    //
    //     print!("{:?}", bytes);
    // }

    #[test]
    fn it_works_2() -> Result<(), Box<dyn std::error::Error>> {

        // 4. 构建待加密数据
        let token_data = TokenData {
            u: 611738073981652992,
            r: vec!["user".to_string(), "admin".to_string()],
            a: vec!["read".to_string(), "write".to_string()],
            e: 1735689600,
        };

        // 序列化 → 字节流
        let encoded: Vec<u8> = encode_to_vec(&token_data, bincode::config::standard())?;
        println!("序列化字节: {:?}", &encoded); // 输出前8字节预览
        println!("序列化后大小: {} 字节", encoded.len());

        // 2. 计算哈希值（校验和）
        let mut hasher = XxHash64::with_seed(0); // 种子可自定义
        hasher.write(encoded.as_ref());

        let checksum = hasher.finish();

        println!("初始校验和: {}", checksum);

        // 将校验和和数据组合成一个字节向量
        // 先放校验和(8字节)，再放序列化数据
        let mut combined_data = Vec::with_capacity(8 + encoded.len());
        combined_data.extend_from_slice(&checksum.to_le_bytes()); // 8字节校验和
        combined_data.extend_from_slice(&encoded); // 序列化数据

        // 使用 URL 安全的 Base64 编码（适合 token）
        let token_string = general_purpose::URL_SAFE_NO_PAD.encode(&combined_data);
        println!("Token 长度: {} 字符", token_string.len());
        println!("Token: {}", token_string);


        // 解码
        let decoded_combined = general_purpose::URL_SAFE_NO_PAD.decode(&token_string)?;


        // 分离校验和和数据
        if decoded_combined.len() < 8 {
            return Err("Invalid token format".into());
        }

        let (checksum_bytes, decoded_bytes) = decoded_combined.split_at(8);
        let received_checksum = u64::from_le_bytes(checksum_bytes.try_into().unwrap());


        let mut new_hasher = XxHash64::with_seed(0);
        new_hasher.write(decoded_bytes.as_ref());
        let new_checksum = new_hasher.finish();

        assert_eq!(checksum, new_checksum);

        assert_eq!(checksum, new_checksum);
        assert_eq!(received_checksum, new_checksum);
        println!("校验和验证通过: {}", new_checksum);

        // 反序列化 → 结构体
        let (decoded, _): (TokenData, usize) = decode_from_slice(&decoded_bytes, bincode::config::standard())?;
        assert_eq!(token_data.u, decoded.u);
        println!("反序列化结果: {:?}", decoded);


        Ok(())
    }

}